package com.zjw.demo.vertx.starter.router;

import com.zjw.demo.vertx.starter.config.ApplicationConfig;
import com.zjw.demo.vertx.starter.core.Reflector;
import com.zjw.demo.vertx.starter.core.ioc.IOCBeanInfo;
import com.zjw.demo.vertx.starter.core.ioc.IOCObserver;
import com.zjw.demo.vertx.starter.core.ioc.IOCScope;
import com.zjw.demo.vertx.starter.utils.LogUtils;
import io.vertx.ext.web.Router;

import java.util.List;

/**
 * @see RouterMethodParser
 */
public final class RouterDispatcher {

  private static final String TAG = "RouterDispatcher";

  private static final RouterMethodParser methodParser = new RouterMethodParser();

  public static void dispatchRouter(Router router) {
    LogUtils.debug(TAG, "start");

    dispatchRouterInterceptor(router);

    methodParser.prepareParse(router);
    IOCScope.globalScope.registerRefreshObserver(new IOCObserver() {
      @Override
      public void onRefresh(Class<?> clazz) {
        if (!clazz.isAnnotationPresent(VertxRouter.class)) {
          return;
        }
        Object iRouter = Reflector.instanceEmptyConstructor(clazz);
        if (iRouter == null) {
          throw new IllegalArgumentException("@VertxRouter must provider EmptyConstructor");
        }

        methodParser.parse(iRouter);
        IOCScope.globalScope.putBean(iRouter.getClass(), iRouter);
        LogUtils.debug(TAG, "dispatcherRouter success " + iRouter.getClass().getName());
      }

      @Override
      public void onInject(IOCBeanInfo o) {

      }

      @Override
      public void onComplete() {

      }
    });

    LogUtils.debug(TAG, "end");
  }

  private static void dispatchRouterInterceptor(Router router) {
    List<IRouterInterceptor> iRouterInterceptors = Reflector.reflectPackageClassAndInstance(ApplicationConfig.getString("router.interceptor.scan.path"), IRouterInterceptor.class);
    for (IRouterInterceptor iRouterInterceptor : iRouterInterceptors) {
      iRouterInterceptor.onInterceptor(router);
      LogUtils.debug(TAG, "dispatchRouterInterceptor success " + iRouterInterceptor.getClass().getName());
    }
  }
}
